﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Narwhunderful.Aphelia.Framework.Graphics;

namespace Narwhunderful.Aphelia.Framework.UI
{
    public class UIComponentCollection<T> : DrawableComponentCollection<T> where T : UIComponent
    {

        HUD _hud = null;
        protected internal HUD HUD
        {
            get
            {
                return _hud;
            }
        }

        UIComponent _parent = null;
        internal UIComponent Parent
        {
            get
            {
                return _parent;
            }
            set
            {
                _parent = value;
                if (base.UpdatableComponents.Count > 0)
                {
                    for (int x = 0; x < base.UpdatableComponents.Count; x++)
                    {
                        base.UpdatableComponents[x].Parent = value;
                    }
                }
            }
        }

        UIScreen _parentScreen = null;
        internal UIScreen ParentScreen
        {
            get
            {
                return _parentScreen;
            }
            set
            {
                _parentScreen = value;
                if (base.UpdatableComponents.Count > 0)
                {
                    for (int x = 0; x < base.UpdatableComponents.Count; x++)
                    {
                        base.UpdatableComponents[x].ParentScreen = value;
                    }
                }
            }
        }

        SpriteBatch _spriteBatch = null;
        internal SpriteBatch SpriteBatch
        {
            get
            {
                return _spriteBatch;
            }
            set
            {
                _spriteBatch = value;
                if (base.UpdatableComponents.Count > 0)
                {
                    for (int x = 0; x < base.UpdatableComponents.Count; x++)
                    {
                        base.UpdatableComponents[x].SpriteBatch = value;
                    }
                }
            }
        }

        IComparer<T> _horizontalNavigableComponentComparer = new UIHorizontalNavigableComponentComparer<T>();
        protected virtual IComparer<T> HorizontalNavigableComponentComparer
        {
            get
            {
                return _horizontalNavigableComponentComparer;
            }
            set
            {
                _horizontalNavigableComponentComparer = value;
            }
        }

        IComparer<T> _verticalNavigableComponentComparer = new UIVerticalNavigableComponentComparer<T>();
        protected virtual IComparer<T> VerticalNavigableComponentComparer
        {
            get
            {
                return _verticalNavigableComponentComparer;
            }
            set
            {
                _verticalNavigableComponentComparer = value;
            }
        }

        List<T> _horizontalNavigableComponents = new List<T>();
        public virtual List<T> HorizontalNavigableComponents
        {
            get
            {
                return _horizontalNavigableComponents;
            }
        }

        List<T> _verticalNavigableComponents = new List<T>();
        public virtual List<T> VerticalNavigableComponents
        {
            get
            {
                return _verticalNavigableComponents;
            }
        }

        public UIComponentCollection(HUD hud, UIComponent parentComponent, UIScreen parentScreen, SpriteBatch spriteBatch)
            : base()
        {
            _hud = hud;
            _parent = parentComponent;
            _parentScreen = parentScreen;
            _spriteBatch = spriteBatch;
        }

        #region IDisposable

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _horizontalNavigableComponents.Clear();
                _verticalNavigableComponents.Clear();
            }
            base.Dispose(disposing);
        }

        #endregion

        #region IComponentCollection

        public override void Add(T component, bool sortComponents)
        {
            if (!_hud.ComponentNames.ContainsKey(component.Name)) _hud.ComponentNames.Add(component.Name, null);
            component.Parent = _parent;
            component.ParentScreen = _parentScreen;
            component.SpriteBatch = _spriteBatch;
            component.OnAdding(this, new EventArgs());
            base.Add(component, sortComponents);
            component.OnAdded(this, new EventArgs());
        }

        public override void Remove(T component, bool sortComponents)
        {
            component.OnRemoving(this, new EventArgs());
            base.Remove(component, sortComponents);
            component.OnRemoved(this, new EventArgs());
        }

        protected override void OnComponentAdded(ComponentEventArgs<T> e)
        {
            _horizontalNavigableComponents.Add(e.Component);
            _verticalNavigableComponents.Add(e.Component);
            base.OnComponentAdded(e);
        }

        protected override void OnComponentRemoved(ComponentEventArgs<T> e)
        {
            _horizontalNavigableComponents.Remove(e.Component);
            _verticalNavigableComponents.Remove(e.Component);
            base.OnComponentRemoved(e);
        }

        protected override void OnSorting()
        {
            if (_horizontalNavigableComponentComparer != null) _horizontalNavigableComponents.Sort(_horizontalNavigableComponentComparer);
            if (_verticalNavigableComponentComparer != null) _verticalNavigableComponents.Sort(_verticalNavigableComponentComparer);
            base.OnSorting();
        }

        #endregion

        public override void Draw(GameTime gameTime)
        {
            for (int x = 0; x < base.DrawableComponents.Count; x++) base.DrawableComponents[x].Draw(gameTime);
        }

    }

}
